﻿namespace Pottery.Module.Store.Models
{
    using System;
    using System.Data.SqlTypes;
    using System.Runtime.Serialization;
    using Pottery.Model.Infrastructure;

    [DataContract]
    public class UserHistory : IAssignable, IValidatable, INullable
    {
        #region Constructors

        /// <summary>
        /// Initializes default user history
        /// </summary>
        public UserHistory() : this(string.Empty, string.Empty, string.Empty) { }

        /// <summary>
        /// Initializes new user history
        /// </summary>
        /// <param name="userLogin">TODO:Desciption</param>
        /// <param name="actionInSystem">TODO:Desciption</param>
        /// <param name="actionDate">TODO:Desciption</param>
        /// <param name="description">TODO:Desciption</param>
        public UserHistory(string userLogin, string actionInSystem,  string description)
        {
            UserLogin = userLogin;
            ActionInSystem = actionInSystem;
            ActionDate = DateTime.Now;
            Description = description;
            m_null = false;
        }

        #endregion

        #region Properties

        [DataMember(Order = 1)]
        public string UserLogin
        {
            get { return m_UserLogin; }
            set
            {
                if (!IsNull)
                    m_UserLogin = value;
            }
        }

        [DataMember(Order = 2)]
        public string ActionInSystem
        {
            get { return m_ActionInSystem; }
            set
            {
                if (!IsNull)
                    m_ActionInSystem = value;
            }
        }

        [DataMember(Order = 3)]
        public DateTime ActionDate
        {
            get { return m_ActionDate; }
            set
            {
                if (!IsNull)
                    m_ActionDate = value;
            }
        }

        [DataMember(Order = 4)]
        public string Description
        {
            get { return m_Description; }
            set
            {
                if (!IsNull)
                    m_Description = value;
            }
        }

        #endregion

        #region IAssignable Implementation

        public void AssignTo(object obj)
        {
            if (IsNull)
                throw new InvalidOperationException();

            if (obj == null)
                throw new ArgumentNullException();

            if (obj is UserHistory)
            {
                UserHistory user = obj as UserHistory;

                user.UserLogin = UserLogin;
                user.ActionInSystem = ActionInSystem;
                user.ActionDate = ActionDate;
                user.Description = Description;

                return;
            }

            throw new NotSupportedException();
        }

        #endregion

        #region IValidatable Implementation

        public bool Validate()
        {
            bool result = true;

            if (string.IsNullOrEmpty(m_UserLogin) || string.IsNullOrWhiteSpace(m_UserLogin))
                result = false;
            else if (m_UserLogin.Length < ModelConstants.MIN_LOGIN_LENGTH || m_UserLogin.Length > ModelConstants.MAX_LOGIN_LENGTH)
                result = false;
            else if (m_UserLogin.Contains(ModelConstants.SPACE))
                result = false;
            else if (m_ActionInSystem.Length > ModelConstants.ACTION_LENGTH)
                result = false;
            else if (m_Description.Length > ModelConstants.DESCRIPTION_LENGTH)
                result = false;

            return result;
        }

        #endregion

        #region INullable Implementation

        public bool IsNull
        {
            get { return m_null; }
        }

        public static UserHistory Null
        {
            get
            {
                UserHistory us = new UserHistory();
                us.m_null = true;
                return us;
            }
        }

        #endregion

        #region Fields

        private string m_UserLogin = default(string);
        private string m_ActionInSystem = default(string);
        private DateTime m_ActionDate = default(DateTime);
        private string m_Description = default(string);
        private bool m_null = false;

        #endregion
    }
}
